/**
 * @author QL
 * @date 2022-02-21 14:58:03
 * @version V..
 * @description openLayers底图配置对象初始化, 基础api二次包装和简单的复合包装
 */
import Map from "ol/Map";
import View from "ol/View";
import { defaults } from "ol/control";

import Feature from 'ol/Feature'
import Point from 'ol/geom/Point'
import { Style, Icon } from 'ol/style'

import {
    Tile as TileLayer,
    Vector as VectorLayer
} from "ol/layer";

import {
    XYZ,
    Vector as VectorSource
} from "ol/source";

class MapClass {
    /**
     * @author QL
     * @functionName constructor
     * @param { Object } con 底图基础配置属性的对象  
     * @param { String } containerId 底图 DOM容器的 id 属性值
     * @date 2022-02-21 14:59:30
     * @version V..
     * @description 类构造方法
     */
    constructor(con, containerId) {
        // 使用高德xyz底图瓦片服务
        this.tileLayer = new TileLayer({
            source: new XYZ({
                url: con.tileLayer_config.url,
            }),
        });

        // 创建底图配置实例
        this.baseMap = new Map({
            layers: [this.tileLayer],
            target: containerId, // 

            view: new View(con.view_config),

            controls: defaults(con.controls_config.defaults).extend(con.controls_config.extend),
        });
    }

    /**
     * @author QL
     * @date 2022-02-28 14:52:23
     * @version V..
     * @description 二次包装基础api
     */
    /**
     * @author QL
     * @functionName addControl
     * @param { Object } controlObj 底图控制对象实例
     * @date 2022-02-28 15:02:51
     * @version V..
     * @description 新增指定控件对象的底图控件
     */
    addControl(controlObj) {
        this.baseMap.addControl(controlObj);
    }

    /**
     * @author QL
     * @functionName removeControl
     * @param { Object } controlObj 底图控制对象实例
     * @date 2022-02-28 15:02:51
     * @version V..
     * @description 移除指定控件对象的底图控件
     */
    removeControl(controlObj) {
        this.baseMap.removeControl(controlObj);
    }

    /**
     * @author QL
     * @functionName instantiatedFeatures
     * @param { Array } lonlatList 点坐标集合
     * @param { Object } featureConfig 要素特征信息配置对象
     * @param { Object } featureStyle 要素样式配置对象
     * @date 2022-03-01 09:35:05
     * @version V..
     * @description 使用Feature类，根据传入的坐标列表数据，一个个生成要素实例，构成要素列表
     */
    instantiatedFeatures(lonlatList, featureConfig = {}, featureStyle =
        {
            anchor: [0.5, 1],// 显示位置
            size: [32, 32],// 尺寸
            imageSize: [32, 32],// 尺寸
            src: require('./assets/thumbtack.png')// 图片url
        }) {
        let features = [];
        lonlatList.forEach((lonlat, index) => {
            // 实例化要素
            let feature = new Feature({
                id: `${index}`,
                geometry: new Point(lonlat),
                checked: false,
            });

            // 如果需要给要素附加一些自定义数据
            feature.set('data', featureConfig);

            // 设置要素的样式
            feature.setStyle([
                new Style({
                    image: new Icon(featureStyle)
                })
            ])

            features.push(feature);
        })
        return features;
    }

    /**
     * @author QL
     * @functionName instantiatedVectorLayer
     * @param { Array[Feature] } features 
     * @date 2022-03-01 09:47:19
     * @version V..
     * @description 使用VectorLayer 根据要素实例的列表，生成矢量源， 初始化矢量图层实例 
     */
    instantiatedVectorLayer(features) {
        // 实例化矢量源
        let vectorSource = new VectorSource({
            features: features
        })

        // 实例化矢量图层
        let vectorLayer = new VectorLayer({
            source: vectorSource
        })
        return vectorLayer
    }

    /**
     * @author QL
     * @functionName move2Point
     * @param { Array } point 点坐标二值数组
     * @param { Number } zoom 缩放比例
     * @date 2022-02-28 14:32:10
     * @version V..
     * @description 将中心视野，按照指定缩放比例，移动至指定坐标点
     */
    move2Point(point, zoom) {
        this.baseMap.getView()
            .animate({
                center: point,
                zoom: zoom,
                duration: 1200,
            });
    }

    /**
     * @author QL
     * @date 2022-02-21 15:14:24
     * @description getters
     */
    _getTileLayer() {
        return this.tileLayer;
    }
    _getBaseMap() {
        return this.baseMap;
    }

    /**
     * @author QL
     * @date 2022-02-21 15:14:24
     * @description setters
     */
    _setTileLayer(type, source) {
        this.tileLayer = new TileLayer({
            source: source
        });
    }
    _setBaseMap(con, containerId) {
        this.baseMap = new Map({
            layers: [this.tileLayer],
            target: containerId, // DOM容器的id

            view: new View(con.view_config),

            controls: defaults(con.controls_config.defaults).extend(con.controls_config.extend),
        })
    }
}

export default MapClass;